package org.kingtop.shiro.realms;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.kingtop.cache.app.AuthorityCacheUtil;
import org.kingtop.cache.app.RoleCacheUtil;
import org.kingtop.cache.app.UserCacheUtil;
import org.kingtop.model.IUserPO;
import org.kingtop.service.IAuthorityService;
import org.kingtop.service.IRoleService;
import org.kingtop.service.IUserService;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;


/**
 * 该类主要用于用于手动从缓存中拿出用户权限，构建给shiro用的权限体系
 * <p>
 * User: chen jinbo
 * <p>
 * Date: 17-12-16
 * <p>
 * Version: 1.2
 */
public class UserRealm extends AuthorizingRealm {

	private IAuthorityService permissionService;

	public IAuthorityService getPermissionService() {
		return permissionService;
	}

	@Resource
	public void setPermissionService(IAuthorityService permissionService) {
		this.permissionService = permissionService;
	}

	private IRoleService roleService;

	public IRoleService getRoleService() {
		return roleService;
	}

	@Resource
	public void setRoleService(IRoleService roleService) {
		this.roleService = roleService;
	}
	
	private IUserService userService;

	public IUserService getUserService() {
		return userService;
	}

	@Resource
	public void setUserService(IUserService userService) {
		this.userService = userService;
	}

	public UserRealm() {
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String username = (String) principals.getPrimaryPrincipal();

		Set<String> roles = RoleCacheUtil.getRoleSignsByUserName(username);
		Set<String> authorities = new HashSet<>();
		//与角色相关的权限
		if(roles != null && roles.size() > 0){
			for (String roleSign : roles) {
				Set<String> roleAuthoritys = AuthorityCacheUtil.getAuthoritySignsByRole(roleSign);
				if(roleAuthoritys != null && roleAuthoritys.size() > 0) {
                    authorities.addAll(roleAuthoritys);
                }
			}
		}
		//与用户直接关系的权限
		Set<String> userAuthoritys = AuthorityCacheUtil.getAuthoritySignsByUser(username);
		if(userAuthoritys != null && userAuthoritys.size() > 0) {
            authorities.addAll(userAuthoritys);
        }
		
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roles);
		authorizationInfo.setStringPermissions(authorities);
		
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

		String username = (String) token.getPrincipal();

		IUserPO user = UserCacheUtil.get(username);
		if (user == null) {
			// 没找到帐号
			throw new UnknownAccountException();
		}

		if (user.getLocked() == 1) {
			// 帐号锁定
			throw new LockedAccountException();
		}

		// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(),
				user.getPassword(),
				// salt=username+salt
				ByteSource.Util.bytes(user.getUserName() + user.getSalt()),
				getName()
		);
		return authenticationInfo;
	}

}
